package com.cjx.myself.service.impl.rce;

import com.cjx.myself.service.rce.RceService;
import com.cjx.myself.util.Security;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Service
public class RceServiceImpl implements RceService {

    @Override
    public String rce1(String filepath) throws IOException {
        String[] cmdList = {filepath};

        ProcessBuilder pb = new ProcessBuilder(cmdList);
        pb.redirectErrorStream(true);

        Process process = pb.start();

        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        StringBuilder output = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

        return output.toString();
    }

    @Override
    public String rce2(String filepath) throws IOException {
        if (!Security.checkOs(filepath)) {

            String[] cmdList = {"sh", "-c", "ls -l " + filepath};

            ProcessBuilder pb = new ProcessBuilder(cmdList);
            pb.redirectErrorStream(true);

            Process process = pb.start();

            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            StringBuilder output = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }

            return output.toString();
        } else {
            return "检测到非法命令注入";
        }
    }

    @Override
    public String rce3(String cmd) throws Exception {
        Class clazz = Class.forName("java.lang.ProcessImpl");
        Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
        method.setAccessible(true);

        Process process = (Process) method.invoke(null, new String[]{cmd}, null, null, null, false);

        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        StringBuilder output = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            output.append(line).append("\n");
        }

        return output.toString();
    }

    @Override
    public String rce4(String cmd) throws IOException {
        StringBuilder sb = new StringBuilder();
        String line;

        try {
            Process proc = Runtime.getRuntime().exec(cmd);

            // 读取命令的输出
            InputStream inputStream = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    @Override
    public String rce5(String cmd) throws IOException {
        StringBuilder sb = new StringBuilder();
        String line;

        // 定义命令白名单
        Set<String> commands = new HashSet<>();
        commands.add("ls");
        commands.add("pwd");

        // 检查用户提供的命令是否在白名单中
        String command = cmd.split("\\s+")[0];
        if (!commands.contains(command)) {
            return "不在白名单中";
        }

        try {
            Process proc = Runtime.getRuntime().exec(cmd);

            InputStream inputStream = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    @Override
    public void rce6(String file) {
        try {
            Runtime rt = Runtime.getRuntime();
            // 加载动态链接库
            rt.load(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void rce7(String cmd) {
        try {
            // java.lang.RunTime
            Class<?> aClass = Class.forName(new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101}));

            // getTime()
            Method getTime = aClass.getDeclaredMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));
            Object Runtime = getTime.invoke(null);

            // exec()
            Method exec = aClass.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);
            exec.invoke(Runtime, cmd);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
